home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / rs232c16.zip / RS_DEMO.C next >
C/C++ Source or Header  |  1995-01-21  |  14KB  |  472 lines

  1. /*
  2.  
  3.    RS_DEMO: Terminal program to demonstrate most of the functions
  4.    available with RS232.C.
  5.  
  6.    C. Karcher
  7.  
  8. */
  9.  
  10. #include<conio.h>
  11. #include<dos.h>
  12. #include"rs232.c"           /* full path for rs232.c */
  13.  
  14. #define BUF_SIZ 1024U       /* 1K input and output buffers */
  15.  
  16. int initialize(char);       /* Draws screen and initializes port */
  17. void scr_update(int, int);  /* Redefines text window and positions cursor */
  18. void update(int);           /* Decodes function keys and takes appropriate
  19.                                action.  Updates port status display */
  20. int end_it(void);           /* Restores text window and closes port prior
  21.                                to exiting */
  22.  
  23. int loc_echo,add_nl;        /* global operating mode flags */
  24. char *in_buf,*out_buf;      /* global buffer pointers */
  25.  
  26. int port_ok;
  27.  
  28. main()
  29. {
  30.  
  31.   extern int loc_echo,add_nl;
  32.   char buf1[BUF_SIZ],buf2[BUF_SIZ],in_lin[BUF_SIZ]; /* declare buffers */
  33.   int ip,i_cnt,c,k = 1;
  34.  
  35.   ctrlbrk(end_it); /* set up control/break routine to insure port is
  36.                       properly close */
  37.  
  38.   in_buf = buf1; /* initialize global buffer pointers */
  39.   out_buf = buf2;
  40.  
  41.   port_ok = initialize('1'); /* draw screen and initialize com port 1 */
  42.  
  43.   loc_echo = add_nl = 0; /* init. misc. options */
  44.  
  45.   /* become a terminal */
  46.   do{
  47.     if(port_ok > 0){ /* if port was initialized succesfully */
  48.       if((i_cnt = rs_inrcvd()) != 0){ /* anything in input buffer ? */
  49.         if(i_cnt > 1){ /* more than one byte, use rs_getstr to retrieve */
  50.           rs_getstr(i_cnt,in_lin);
  51.           }
  52.         else
  53.           *in_lin = rs_getbyt(); /* only one byte, use rs_getbyt */
  54.         for(ip = 0;ip < i_cnt;ip++){  /* display received bytes */
  55.           c = *(in_lin + ip);
  56.           putch(c);
  57.           if(add_nl && c == 0x0D) /* add NL to CR if applicable */
  58.             putch(0x0A);
  59.           }
  60.         }
  61.       update(0); /* in case any dynamics have changed */
  62.       }
  63.     if(rs_keyhit()){ /* any keyhits ? */
  64.       if((k = getch()) == 0){ /* if first byte 0, it's a function key */
  65.         k = getch();          /* get next byte and call update */
  66.         update(k);
  67.         }
  68.       else if(port_ok > 0){  /* otherwise if port's active, send the byte */
  69.         while(rs_sndbyt(k)){
  70.           if(rs_keyhit()){
  71.             k = getch();
  72.             if(k == 27)
  73.               break;
  74.             else
  75.               ungetch(k);
  76.             }
  77.           }
  78.         if(loc_echo){ /* display it if local echo on */
  79.           putch(k);
  80.           if(add_nl && k == 0x0D) /* add NL to CR if applicable */
  81.             putch(0x0A);
  82.           }
  83.         }
  84.       }
  85.     }while(k != 27); /* fall out if ESC */
  86.  
  87.   end_it();
  88.   return 0;
  89.  
  90. }
  91.  
  92. void update(int key)
  93. {
  94.  
  95.   int port_update,x_save,y_save,tmp_i;
  96.   unsigned tmp_u;
  97.   extern int loc_echo,add_nl;
  98.   extern char *in_buf,*out_buf;
  99.   long baud[] = {110L,300L,600L,1200L,2400L,4800L,9600L,19200L,
  100.                  38400L,57600L,115200L};
  101.   char parity[] = "NEOSM";
  102.   char *flow_str[] = {"None","XON/XOFF","CTS","DSR","RI","DCD"};
  103.   char *flwstat_str[] = {"Output Enabled","Output Disabled"};
  104.   char *line_str[] = {"Off","On"};
  105.   char *error_str[] = {"None","Break Detected","Framing Error",
  106.                        "Parity Error","Rcv Data Overrun",
  107.                        "Rcv Buffer Overflow"};
  108.   static struct{ /* static struct to hold user selectable characteristics */
  109.     char port;
  110.     int speed;
  111.     int par;
  112.     char dbits;
  113.     char sbits;
  114.     int flw_cnt;
  115.     int dtr;
  116.     int rts;
  117.     int loc_echo;
  118.     int add_nl;
  119.     }select = {'1',4,0,'8','1',RS_FLWOFF,0,0,0,0};
  120.  
  121.   static struct{ /* static struct to hold dynamic statistics */
  122.     int flow_stat;
  123.     int mod_stat;
  124.     unsigned rcv_buf;
  125.     unsigned xmit_buf;
  126.     int error;
  127.     }dynamic;
  128.  
  129.   port_update = 0; /* flag to indicate whether or not port should be closed
  130.                       and reopened with new parameters */
  131.  
  132.   /* Determine action from key code if one was sent.  If port is inactive
  133.      except only command to change port number */
  134.   if(key != 0 && (port_ok > 0 || key == 0x3B)){
  135.     switch(key){
  136.       case 0x3B: /* F1 key - port ID */
  137.         if(++select.port > '4')
  138.           select.port = '1';
  139.         select.speed = 4;
  140.         select.par = 0;
  141.         select.dbits = '8';
  142.         select.sbits = '1';
  143.         port_ok = initialize(select.port);
  144.         break;
  145.       case 0x3C: /* F2 key - baud rate */
  146.         if(++select.speed > 10)
  147.           select.speed = 0;
  148.         port_update = 1;
  149.         scr_update(25,1);
  150.         cprintf("%-6ld",baud[select.speed]);
  151.         scr_update(0,0);
  152.         break;
  153.       case 0x3D: /* F3 key - parity */
  154.         if(++select.par > 4)
  155.           select.par = 0;
  156.         port_update = 1;
  157.         scr_update(44,1);
  158.         putch(parity[select.par]);
  159.         scr_update(0,0);
  160.         break;
  161.       case 0x3E: /* F4 key - data bits */
  162.         if(++select.dbits > '8')
  163.           select.dbits = '7';
  164.         port_update = 1;
  165.         scr_update(61,1);
  166.         putch(select.dbits);
  167.         scr_update(0,0);
  168.         break;
  169.       case 0x3F: /* F5 key - stop bits */
  170.         if(++select.sbits > '2')
  171.           select.sbits = '1';
  172.         port_update = 1;
  173.         scr_update(78,1);
  174.         putch(select.sbits);
  175.         scr_update(0,0);
  176.         break;
  177.       case 0x40: /* F6 key - Set Flow Control */
  178.         if(++select.flw_cnt > 5)
  179.           select.flw_cnt = 0;
  180.         switch(select.flw_cnt){
  181.           case 0:
  182.             rs_setflow(RS_FLWOFF);
  183.             break;
  184.           case 1:
  185.             rs_setflow(RS_FLWXON,RS_XON,RS_XOFF);
  186.             break;
  187.           case 2:
  188.             rs_setflow(RS_FLWHDW,RS_FLWCTS);
  189.             break;
  190.           case 3:
  191.             rs_setflow(RS_FLWHDW,RS_FLWDSR);
  192.             break;
  193.           case 4:
  194.             rs_setflow(RS_FLWHDW,RS_FLWRI);
  195.             break;
  196.           case 5:
  197.             rs_setflow(RS_FLWHDW,RS_FLWDCD);
  198.             break;
  199.           }
  200.         scr_update(21,3);
  201.         cprintf("%-8s",flow_str[select.flw_cnt]);
  202.         scr_update(0,0);
  203.         break;
  204.       case 0x41: /* F7 key - Clear Xmit buffer */
  205.         rs_clrout();
  206.         break;
  207.       case 0x42: /* F8 key - Clear Rcv buffer */
  208.         rs_clrin();
  209.         break;
  210.       case 0x43: /* F9 - toggle DTR */
  211.         if(select.dtr == 0){
  212.           select.dtr = 1;
  213.           rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINON);
  214.           }
  215.         else{
  216.           select.dtr = 0;
  217.           rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINOFF);
  218.           }
  219.         scr_update(10,5);
  220.         cprintf("%-3s",line_str[select.dtr]);
  221.         scr_update(0,0);
  222.         break;
  223.       case 0x44: /* F10 - toggle RTS */
  224.         if(select.rts == 0){
  225.           select.rts = 1;
  226.           rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINON);
  227.           }
  228.         else{
  229.           select.rts = 0;
  230.           rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINOFF);
  231.           }
  232.         scr_update(24,5);
  233.         cprintf("%-3s",line_str[select.rts]);
  234.         scr_update(0,0);
  235.         break;
  236.       case 0x54: /* sh/F1 key - local echo */
  237.         if(select.loc_echo == 1){
  238.           select.loc_echo = 0;
  239.           loc_echo = 0; /* update global variable */
  240.           }
  241.         else{
  242.           select.loc_echo = 1;
  243.           loc_echo = 1; /* update global variable */
  244.           }
  245.         scr_update(47,5);
  246.         cprintf("%-3s",line_str[select.loc_echo]);
  247.         scr_update(0,0);
  248.         break;
  249.       case 0x55: /* sh/F2 key - add newline to carriage return */
  250.         if(select.add_nl == 1){
  251.           select.add_nl = 0;
  252.           add_nl = 0;    /* update global variable */
  253.           }
  254.         else{
  255.           select.add_nl = 1;
  256.           add_nl = 1;    /* update global variable */
  257.           }
  258.         scr_update(77,5);
  259.         cprintf("%-3s",line_str[select.add_nl]);
  260.         scr_update(0,0);
  261.         break;
  262.       case 0x56: /* sh/F3 key - send break */
  263.         rs_break();
  264.         break;
  265.       case 0x57: /* sh/F4 key - send XON */
  266.         rs_setflow(RS_FLWINS,RS_XON);
  267.         break;
  268.       case 0x58: /* sh/F5 key - send XOFF */
  269.         rs_setflow(RS_FLWINS,RS_XOFF);
  270.       }
  271.     }
  272.  
  273.   if(port_ok <= 0) /* don't continue if port is invalid */
  274.     return;
  275.  
  276.   if(port_update){ /* new port parameters - close and reopen port */
  277.     rs_close();
  278.     select.flw_cnt = 0;
  279.     scr_update(21,3);
  280.     cprintf("%-8s",flow_str[select.flw_cnt]);
  281.     scr_update(0,0);
  282.     rs_initport(select.port,select.speed[baud],parity[select.par],
  283.       select.dbits,select.sbits,BUF_SIZ,in_buf,BUF_SIZ,out_buf);
  284.     }
  285.  
  286.   /* check for changed flow control status */
  287.   if((tmp_i = rs_setflow(RS_FLWSTAT)) != dynamic.flow_stat){
  288.     dynamic.flow_stat = tmp_i;
  289.     scr_update(26,9);
  290.     cprintf("%-15s",flwstat_str[dynamic.flow_stat]);
  291.     scr_update(0,0);
  292.     }
  293.  
  294.   /* check for modem status change */
  295.   tmp_i = rs_modctrl(RS_GETMSR);
  296.   if(tmp_i & 0x0F){  /* if any change bits are set */
  297.     if(tmp_i & RS_CTSCHG){ /* CTS change bit set? */
  298.       scr_update(47,9);
  299.       /* "(tmp_i & RS_CTSSTE) == RS_CTSSTE" equates to one if CTS bit
  300.          is on, otherwise, equates to 0 */
  301.       cprintf("%-3s",line_str[(tmp_i & RS_CTSSTE) == RS_CTSSTE]);
  302.       scr_update(0,0);
  303.       }
  304.     if(tmp_i & RS_DSRCHG){ /* DSR change bit set? */
  305.       scr_update(56,9);
  306.       cprintf("%-3s",line_str[(tmp_i & RS_DSRSTE) == RS_DSRSTE]);
  307.       scr_update(0,0);
  308.       }
  309.     if(tmp_i & RS_RICHG){ /* RI change bit set? */
  310.       scr_update(64,9);
  311.       cprintf("%-3s",line_str[(tmp_i & RS_RISTE) == RS_RISTE]);
  312.       scr_update(0,0);
  313.       }
  314.     if(tmp_i & RS_DCDCHG){ /* DCD change bit set? */
  315.       scr_update(73,9);
  316.       cprintf("%-3s",line_str[(tmp_i & RS_DCDSTE) == RS_DCDSTE]);
  317.       scr_update(0,0);
  318.       }
  319.     }
  320.  
  321.   tmp_u = rs_inrcvd(); /* update "number of bytes in rcv buffer" if changed */
  322.   if(tmp_u != dynamic.rcv_buf){
  323.     dynamic.rcv_buf = tmp_u;
  324.     scr_update(20,10);
  325.     cprintf("%04u",dynamic.rcv_buf);
  326.     scr_update(0,0);
  327.     }
  328.  
  329.   tmp_u = rs_outfre(); /* update "number of bytes in xmit buffer" if changed */
  330.   if(tmp_u != dynamic.xmit_buf){
  331.     dynamic.xmit_buf = tmp_u;
  332.     scr_update(40,10);
  333.     cprintf("%04u",BUF_SIZ - dynamic.xmit_buf);
  334.     scr_update(0,0);
  335.     }
  336.  
  337.   /* Update error status if changed.  Error status is displayed for
  338.      approx. 3 seconds */
  339.   tmp_i = rs_error();
  340.   if(tmp_i){
  341.     if(tmp_i & RS_BKDT)
  342.       tmp_i = 1;
  343.     else if(tmp_i & RS_FERR)
  344.       tmp_i = 2;
  345.     else if(tmp_i & RS_PERR)
  346.       tmp_i = 3;
  347.     else if(tmp_i & RS_ROER)
  348.       tmp_i = 4;
  349.     else if(tmp_i & RS_RBER)
  350.       tmp_i = 5;
  351.     dynamic.error = tmp_i;
  352.     scr_update(54,10);
  353.     cprintf("%-19s",error_str[tmp_i]);
  354.     scr_update(0,0);
  355.     rs_timer(RS_CLRTIM); /* clear timer */
  356.     }
  357.   else if(dynamic.error){
  358.     if(rs_timer(RS_GETTIM) > 50){ /* after about 3 seconds, clear error */
  359.       dynamic.error = 0;
  360.       scr_update(54,10);
  361.       cprintf("%-19s",error_str[0]);
  362.       scr_update(0,0);
  363.       }
  364.     }
  365.  
  366. }
  367.  
  368. int initialize(char port)
  369. {
  370.   int x,port_ok;
  371.   char *line_str[] = {"Off","On"};
  372.   char txt[] = "  (F1)Port:   (F2)Speed:2400    (F3)Parity:N  (F4)Data "
  373.                "Bits:8  (F5)Stop Bits:1\r\n\n   (F6)Flow Control:None  "
  374.                "      (F7)Clear Xmit Buffer    (F8)Clear Rcv Buffer\r\n"
  375.                "\n (F9)DTR:Off  (F10)RTS:Off  (Sh/F1)Local Echo:Off  (S"
  376.                "h/F2)Add NewLine to CR:Off\r\n\n  (Sh/F3)Send Break    "
  377.                "(Sh/F4)Send XON    (Sh/F5)Send XOFF   (ESC)End Program\r"
  378.                "\n\n     Flow Control Status:Output Enabled   CTS:     "
  379.                "DSR:     RI:     DCD:\r\n        Rcv Buffer:0000    X"
  380.                "mit Buffer:0000    Error:None";
  381.   extern char *in_buf,*outbuf;
  382.  
  383.  
  384.   window(1,1,80,25);
  385.   clrscr();
  386.  
  387.   cprintf("%s",txt);
  388.  
  389.   rs_close();
  390.   port_ok = rs_initport(port,RS_B2400,RS_NOPAR,RS_DBIT8,RS_SBIT1,
  391.                         BUF_SIZ,in_buf,BUF_SIZ,out_buf);
  392.  
  393.   gotoxy(12,1);
  394.   putch(port);
  395.  
  396.   /* if port initialization OK, get and display modem status and control */
  397.   if(port_ok > 0){
  398.     x = rs_modctrl(RS_GETMSR);
  399.     gotoxy(47,9);
  400.     if(x & RS_CTSSTE)
  401.       cputs(line_str[1]);
  402.     else
  403.       cputs(line_str[0]);
  404.     gotoxy(56,9);
  405.     if(x & RS_DSRSTE)
  406.       cputs(line_str[1]);
  407.     else
  408.       cputs(line_str[0]);
  409.     gotoxy(64,9);
  410.     if(x & RS_RISTE)
  411.       cputs(line_str[1]);
  412.     else
  413.       cputs(line_str[0]);
  414.     gotoxy(73,9);
  415.     if(x & RS_DCDSTE)
  416.       cputs(line_str[1]);
  417.     else
  418.       cputs(line_str[0]);
  419.     /* set DTR and RTS off */
  420.     rs_modctrl(RS_WRTMCR,RS_MCRDTR | RS_MCRRTS,RS_LINOFF);
  421.     }
  422.   else{ /* if port initialization not OK, display message */
  423.     gotoxy(14,1);
  424.     cprintf("%-65s","UNAVAILABLE");
  425.     }
  426.  
  427.   gotoxy(1,8);
  428.   for(x = 0;x < 80;x++)
  429.     putch(196);
  430.  
  431.   gotoxy(1,11);
  432.   for(x = 0;x < 80;x++)
  433.     putch(196);
  434.  
  435.   window(1,12,80,25);
  436.  
  437.   return port_ok; /* value returned by rs_initport */
  438.  
  439. }
  440.  
  441. void scr_update(int x, int y)
  442. {
  443.  
  444.   static int x_sav,y_sav;
  445.  
  446.   /* If x != 0, save current cursor position, relocate cursor to new x
  447.      and y.  If x = 0, set window back to terminal window and restore
  448.      old cursor postion */
  449.   if(x){
  450.     x_sav = wherex();
  451.     y_sav = wherey();
  452.     window(1,1,80,25);
  453.     gotoxy(x,y);
  454.     }
  455.   else{
  456.     window(1,12,80,25);
  457.     gotoxy(x_sav,y_sav);
  458.     }
  459.  
  460. }
  461.  
  462. int end_it(void)
  463. {
  464.  
  465.   window(1,1,80,25);  /* restore window to full screen */
  466.   gotoxy(1,24);       /* put cursor at bottom of window */
  467.   rs_close();         /* close the port */
  468.  
  469.   return 1;
  470.  
  471. }
  472.